package com.lwl.blue.commont.config;

import com.alibaba.fastjson.JSON;
import com.lwl.blue.commont.base.BizException;
import com.lwl.blue.commont.base.Const;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.stereotype.Component;

import javax.validation.ConstraintViolation;
import javax.validation.Validation;
import javax.validation.Validator;
import java.util.ArrayList;
import java.util.List;
import java.util.Set;

/**
 * 其他层校验AOP
 *
 * @author lwl
 */
@Aspect
@Component
public class ParamsCheckAspect {
    private static Validator validator;

    static {
        //手动指定校验提示资源（默认在resource目录下ValidationMessages.properties）
        validator = Validation.byDefaultProvider().configure().buildValidatorFactory().getValidator();
    }

    /**
     * 定义接口参数校验切入点
     */
    @Pointcut("@annotation(org.springframework.validation.annotation.Validated))")
    private void validateMethod() {
    }

    @Before("validateMethod()")
    public void before(JoinPoint joinPoint) {
        Object[] args = joinPoint.getArgs();
        MethodSignature signature = (MethodSignature) joinPoint.getSignature();
        // 执行方法参数的校验
        Set<ConstraintViolation<Object>> constraintViolations = validator.forExecutables().validateParameters(joinPoint.getThis(), signature.getMethod(), args);
        List<String> messages = new ArrayList();
        for (ConstraintViolation<Object> error : constraintViolations) {
            messages.add(error.getMessage());
        }
        if (!messages.isEmpty()) {
            throw new BizException(Const.CODE_FAILED, JSON.toJSONString(messages));
        }
    }
}
